﻿using System.Collections.Generic;
using System.IO;

namespace SharpTag.ID3
{
    /// <summary>
    /// Concreate implementation of the <see cref="ITaggedFile"/> interface.
    /// </summary>
    public class MP3File : ITaggedFile
    {
        private FileInfo fileInfo;
        private List<ITag> Tags = new List<ITag>();

        /// <summary>
        /// Class constructor
        /// </summary>
        /// <param name="filePath">Full path of the file.</param>
        public MP3File(string filePath)
        {
            fileInfo = new FileInfo(filePath);
            IsDirty = false;
        }

        /// <summary>
        /// Gets a list of <see cref="ITag"/> objects from the File.
        /// </summary>
        /// <returns>Generic list of <see cref="ITag"/> objects.</returns>
        public List<ITag> GetTags()
        {
            return Tags;
        }

        /// <summary>
        /// Adds an <see cref="ITag"/> object to the File.
        /// </summary>
        /// <param name="tag">An <see cref="ITag"/> object.</param>
        public void AddTag(ITag tag)
        {
            if (!Tags.Contains(tag))
            {
                Tags.Add(tag);
                IsDirty = true;
            }
                
        }

        /// <summary>
        /// Adds a list of <see cref="ITag"/> objects to the File.
        /// </summary>
        /// <param name="tags">A generic list of <see cref="ITag"/> objects.</param>
        public void AddTags(List<ITag> tags)
        {
            foreach (var tag in tags)
            {
                AddTag(tag);
                IsDirty = true;
            }
        }

        /// <summary>
        /// Removes an <see cref="ITag"/> object from the File.
        /// </summary>
        /// <param name="tag">An <see cref="ITag"/> object.</param>
        public void RemoveTag(ITag tag)
        {
            if (Tags.Contains(tag))
            {
                Tags.Remove(tag);
                IsDirty = true;
            }
        }

        /// <summary>
        /// Removes a list of <see cref="ITag"/> objects from the File.
        /// </summary>
        /// <param name="tags">A generic list of <see cref="ITag"/> objects.</param>
        public void RemoveTags(List<ITag> tags)
        {
            foreach (var tag in tags)
            {
                RemoveTag(tag);
                IsDirty = true;
            }
        }

        /// <summary>
        /// Parses the raw tag bytes into the appropriate properties.
        /// </summary>
        /// <param name="tagBytes">A byte array containing the raw tag data.</param>
        public void ParseTag(byte[] tagBytes)
        {
            AbstractTagFactory tagFactory = new ID3TagFactory();
            AddTag(tagFactory.CreateTag(tagBytes, fileInfo.Length));
        }

        /// <summary>
        /// Gets the Size of the File.
        /// </summary>
        public long Size
        {
            get { return fileInfo.Length; }
        }

        /// <summary>
        /// Gets the Path of the File.
        /// </summary>
        public string Path
        {
            get { return fileInfo.FullName; }
        }

        /// <summary>
        /// Gets the Type of the File.
        /// </summary>
        public string Type
        {
            get { return fileInfo.Extension.Remove(0, 1).ToLower(); }
        }

        /// <summary>
        /// Gets whether or not the File has been modified.
        /// </summary>
        public bool IsDirty { get; private set; }
    }
}
